#ifndef SMARTQUERY_H
#define SMARTQUERY_H

#include <QString>
#include <QDebug>
#include <QSqlQueryModel>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QStringList>
#include <QPair>
#include <QVector>
#include <boost/shared_ptr.hpp>
#include "DatabaseWork.h"

namespace DatabaseModule {

	//typedef boost::shared_ptr<QSqlQueryModel> QueryModelPtr;
	typedef boost::shared_ptr<DatabaseWork> DbWorkPtr;
	typedef QPair<QString, QString> StringPair;
	typedef QVector<StringPair> PairVector;

	const QString dbName = "anime_db";

	class SmartQuery {
	public:

		SmartQuery()
			:fieldList(QStringList()), termList(PairVector()), orderList(QStringList()), tableList(QStringList()) {}
		SmartQuery(const QStringList& fields, const PairVector& terms, const QStringList& orders)
			: fieldList(fields), termList(terms), orderList(orders), tableList(QStringList()) {}
		virtual ~SmartQuery() {}

		void setFieldList(const QStringList& fields) {fieldList = fields;}
		QStringList getFieldList() {return fieldList;}
		void setTermList(const PairVector& terms) {termList = terms;}
		PairVector getTermList() {return termList;}
		void setOrderList(const QStringList& orders) {orderList = orders;}
		QStringList getOrderList() {return orderList;}

		QueryModelPtr exec();
		QString generateSqlQuery();

	private:

		QStringList fieldList;
		QStringList tableList;
		PairVector termList;		//1st - term, 2nd - condition
		QStringList orderList;
		DbWorkPtr dbWorker;

		SmartQuery(const SmartQuery&);
		SmartQuery& operator=(const SmartQuery&);

		QString generateSelectCase();
		QString generateFromCase();
		QString generateWhereCase();
		QString generateOrderCase();

		QStringList generateLinkTerms();
		void parseTableList();
		QStringList getIntermediateTables(const QString& source, const QString& destination);

	};

}

#endif //SMARTQUERY_H